import 'dart:io' show File;

import 'package:PollOnLine/utils/ImagePickerUtils.dart';
import 'package:PollOnLine/utils/utils.dart';
import 'package:PollOnLine/utils/video_compress_utils.dart';
import 'package:PollOnLine/widget/picker/camera_utils.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/src/size_extension.dart';

import '../bean/FilePathEntity.dart';
import '../r.dart';
import '../utils/date_time_utils.dart';
import '../values/MyColors.dart';
import 'gallery/gallery.dart';

export '../bean/Media.dart';

///
/// 图片选择
/// 2021-10-29 15:20:26
///

/// 自定义结果回调
typedef OnMediaResultsCallback = void Function(List<Media> imagesList, List<FilePathEntity> filePathList);

final GlobalKey<_ImagesGridviewWidgetState> imagesGridViewKey = GlobalKey(); // imagesGridViewKey.currentState?.clearData();

class ImagesGridviewWidget extends StatefulWidget {
  /// 编辑情况下，带过来的网络图片
  final List<FilePathEntity>? filePathList;

  /// 编辑情况下，带过来的本地图片
  final List<Media>? resultList;

  /// 是否能编辑 来决定显示不显示 图片右上角的删除按钮 和 添加 + 号 按钮 默认 ture
  final bool isWriteAuth;

  /// 是否开启 本地相册 选择权限  默认为false
  final bool isOpenPhoto;

  /// 是否开启 本地文件 选择权限 默认为false
  final bool isOpenFile;

  /// 是否开启 本地可视化采集资料 选择权限 默认为false
  final bool isOpenSelect;

  /// 文件存储路径
  final String? dirName;

  /// 自定义结果回调
  final OnMediaResultsCallback onMediaResultsCallback;

  final int crossAxisCount; // 九宫格 横排的数量

  final int selectNum; //最大选择数量  默认为9

  const ImagesGridviewWidget({
    Key? key,
    this.filePathList,
    this.resultList,
    this.isWriteAuth = true,
    this.isOpenPhoto = false,
    this.isOpenFile = false,
    this.isOpenSelect = false,
    this.dirName,
    required this.onMediaResultsCallback,
    this.crossAxisCount = 3,
    this.selectNum = 9,
  }) : super(key: key);

  @override
  _ImagesGridviewWidgetState createState() => _ImagesGridviewWidgetState();
}

class _ImagesGridviewWidgetState extends State<ImagesGridviewWidget> {
  // 存放本地选择图片和视频的 list
  List<Media> _resultList = [];

  // 存放已经上传的 需要再次编辑的图片的 list
  List<FilePathEntity> _filePathList = [];

  /// 变更 存放选择图片的 list 之后，都要进行回调，来刷新回调的值
  void _upMediaData() {
    widget.onMediaResultsCallback.call(_resultList, _filePathList);
  }

  // 是否显示 + 添加
  bool isShowAdd() {
    int num = 0;
    if (_filePathList.isNotEmpty) {
      num += _filePathList.length;
    }
    if (_resultList.isNotEmpty) {
      num += _resultList.length;
    }
    if (num >= widget.selectNum) {
      return false;
    }
    return true;
  }

  // 还能添加几个图片或者视频
  int surplusSelectNum() {
    int num = 0;
    if (_filePathList.isNotEmpty) {
      num += _filePathList.length;
    }
    if (_resultList.isNotEmpty) {
      num += _resultList.length;
    }
    return num == 0 ? widget.selectNum : widget.selectNum - num;
  }

  @override
  void initState() {
    super.initState();
    // 初始化 存放已经上传的 需要再次编辑的图片的 list
    if (widget.filePathList != null) {
      _filePathList = widget.filePathList!;
    }
    // 本地图片
    if (widget.resultList != null) {
      _resultList = widget.resultList!;
    }
  }

  @override
  Widget build(BuildContext context) {
    var width = MediaQuery.of(context).size.width;
    var gradWidth = width - 30; //9宫格的大小
    var itemWidth = gradWidth / widget.crossAxisCount; //某张图片拖动时 的大小
    return Container(
      margin: const EdgeInsets.only(left: 0, right: 0, top: 0),
      width: gradWidth,
      child: GridView(
        padding: const EdgeInsets.only(top: 0),
        gridDelegate: isPad(context)
            ? SliverGridDelegateWithMaxCrossAxisExtent(
                crossAxisSpacing: 20.r,
                mainAxisSpacing: 20.r,
                childAspectRatio: 1,
                maxCrossAxisExtent: 90,
              )
            : SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: widget.crossAxisCount,
                mainAxisSpacing: 20.r,
                crossAxisSpacing: 20.r,
                childAspectRatio: 1,
              ),
        // physics: BouncingScrollPhysics(),
        shrinkWrap: true,
        //禁止滚动
        physics: const NeverScrollableScrollPhysics(),
        children: buildItems(itemWidth),
      ),
    );
  }

  // 生成GridView的items
  List<Widget> buildItems(var itemWidth) {
    List<Widget> items = [];
    // 先判断有没有 需要初始化的图片或者视频
    if (_filePathList.isNotEmpty) {
      for (var filePath in _filePathList) {
        items.add(ImageUrlItem(itemWidth, filePath, _filePathList.indexOf(filePath)));
      }
    }
    // 然后添加 增加的本地图片或者视频
    for (var result in _resultList) {
      // items.add(draggableItem(itemWidth, image.path));
      items.add(ImageItem(itemWidth, result, _resultList.indexOf(result)));
    }
    // 最后添加 + 号 按钮
    if (widget.isWriteAuth) {
      if (isShowAdd()) {
        items.add(pickerImageButton(itemWidth));
      }
    }
    return items;
  }

  // 显示图片
  // 基础展示的item 此处设置width,height对GridView 无效，主要是偷懒给feedback用
  Widget ImageItem(var itemWidth, Media media, int index) {
    return GestureDetector(
      child: Container(
        width: itemWidth,
        height: itemWidth,
        color: Colors.black45,
        child: Stack(
          children: [
            media.galleryMode == GalleryMode.image
                ? Image.file(File(media.path ?? ""), fit: BoxFit.fill, width: itemWidth)
                : Image.file(File(media.thumbPath ?? ""), fit: BoxFit.fill, width: itemWidth),
            Visibility(
              visible: media.galleryMode == GalleryMode.video,
              child: Center(
                child: Image.asset(R.assetsImgIcon57, width: 15.r),
              ),
            ),
            Visibility(
              visible: widget.isWriteAuth,
              child: Positioned(
                right: 1.08.r,
                top: 1.08.r,
                child: GestureDetector(
                  onTap: () {
                    setState(() {
                      _resultList.removeAt(index);
                      _upMediaData();
                    });
                  },
                  child: Container(
                    decoration: const BoxDecoration(
                      color: Colors.black45,
                      shape: BoxShape.circle,
                    ),
                    child: Icon(Icons.close, color: Colors.white, size: 15.r),
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
      onTap: () {
        List<GalleryModel> list = [];
        for (var element in _resultList) {
          list.add(GalleryModel(
            id: _resultList.indexOf(element).toString(),
            url: element.path ?? "",
            time: element.dateTime,
            address: element.address,
          ));
        }
        gallery(list, showIndex: index);
        // if (media.galleryMode == GalleryMode.video) {
        //   ImagePickersUtils().previewVideo(_resultList, index);
        // } else {
        //   ImagePickersUtils().previewImage(_resultList, index);
        // }
      },
    );
  }

  // 显示网络图片
  // 基础展示的item 此处设置width,height对GridView 无效，主要是e偷懒给feedback用
  Widget ImageUrlItem(var itemWidth, FilePathEntity entity, int index) {
    return GestureDetector(
      child: Container(
        width: itemWidth,
        height: itemWidth,
        color: Colors.black45,
        child: Stack(
          children: [
            Image.network(entity.thumbnailPath!, fit: BoxFit.cover, width: itemWidth),
            Visibility(
              visible: entity.fileType == "mp4",
              child: Center(
                child: Image.asset(R.assetsImgIcon57, width: 15.r),
              ),
            ),
            Visibility(
              visible: widget.isWriteAuth,
              child: Positioned(
                right: 1.08.r,
                top: 1.08.r,
                child: GestureDetector(
                  onTap: () {
                    setState(() {
                      _filePathList.removeAt(index);
                      _upMediaData();
                    });
                  },
                  child: Container(
                    decoration: const BoxDecoration(
                      color: Colors.black45,
                      shape: BoxShape.circle,
                    ),
                    child: Icon(Icons.close, color: Colors.white, size: 20.r),
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
      onTap: () {
        List<GalleryModel> list = [];
        for (var element in _filePathList) {
          list.add(GalleryModel(id: _filePathList.indexOf(element).toString(), url: element.sourcePath ?? ""));
        }
        gallery(list, showIndex: index);
        // if (entity.fileType == "mp4") {
        //   ImagePickersUtils().previewVideoUrl(entity.sourcePath!);
        // } else {
        //   ImagePickersUtils().previewUrlImage(entity.sourcePath!);
        // }
      },
    );
  }

  // + 号 item视图
  Widget pickerImageButton(itemWidth) {
    return GestureDetector(
        onTap: loadImages,
        behavior: HitTestBehavior.opaque,
        child: Container(
          width: itemWidth,
          height: itemWidth,
          color: Colors.transparent,
          child: Image.asset(R.assetsImgIconHome10),
        ));
  }

  /// 点击 添加 加载图片
  Future<void> loadImages() async {
    if (widget.isOpenSelect) {
      showModalBottomSheet(
        context: context,
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.only(topLeft: Radius.circular(13.33.r), topRight: Radius.circular(13.33.r))),
        // isScrollControlled属性，设置为true，弹窗会覆盖整个手机。设置为false，弹窗大概是整个屏幕的9/16高。
        isScrollControlled: true,
        builder: (BuildContext context) {
          return SafeArea(
            child: SingleChildScrollView(
              child: Column(
                children: [
                  SizedBox(
                    width: MediaQuery.of(context).size.width,
                    height: 50.r,
                    child: TextButton(
                      child: Text("照片", style: TextStyle(color: MyColors.FF666666, fontSize: 14.r)),
                      onPressed: () {
                        openCameraImage();
                        Navigator.pop(context);
                      },
                    ),
                  ),
                  const Divider(height: 1, thickness: 1, color: MyColors.FFF5F5F5),
                  SizedBox(
                    width: MediaQuery.of(context).size.width,
                    height: 50.r,
                    child: TextButton(
                      child: Text("视频", style: TextStyle(color: MyColors.FF666666, fontSize: 14.r)),
                      onPressed: () {
                        openCameraVideo();
                        Navigator.pop(context);
                      },
                    ),
                  ),
                  const Divider(height: 1, thickness: 5, color: MyColors.FFF5F5F5),
                  SizedBox(
                    width: MediaQuery.of(context).size.width,
                    height: 50.r,
                    child: TextButton(
                      onPressed: () {
                        Navigator.pop(context);
                      },
                      child: Text("取消", style: TextStyle(color: MyColors.FFE5261E, fontSize: 14.r)),
                    ),
                  ),
                ],
              ),
            ),
          );
        },
      );
    } else {
      openCamera();
    }
  }

  // 打开相机
  Future<void> openCamera() async {
    Media? media = await CameraUtils().takePicture(dirName: widget.dirName);
    if (media != null) {
      setState(() {
        _resultList.add(media);
        _upMediaData();
      });
    }
  }

  // 打开相机
  Future<void> openCameraImage() async {
    XFile? xFile = await ImagePickerUtils().openCameraImage();
    // Media? media = await CameraUtils().openCameraAddWatermark(dirName: widget.dirName);
    if (xFile != null) {
      setState(() {
        Media media = Media();
        media.name = xFile.name;
        media.path = xFile.path;
        media.thumbPath = xFile.path;
        media.dateTime = DateTimeUtils.getNow();
        media.galleryMode = GalleryMode.image;
        _resultList.add(media);
        _upMediaData();
      });
    }
  }

  Future<void> openCameraVideo() async {
    XFile? xFile = await ImagePickerUtils().openCameraVideo();
    if (xFile != null) {
      File thumb = await VideoCompressUtils().getFileThumbnail(xFile.path);
      setState(() {
        Media media = Media();
        media.name = xFile.name;
        media.path = xFile.path;
        media.thumbPath = thumb.path;
        media.dateTime = DateTimeUtils.getNow();
        media.galleryMode = GalleryMode.video;
        _resultList.add(media);
        _upMediaData();
      });
    }
  }
}
